package ForParser;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;

import objects.Mot;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import DB.BddManager;

public class Parser {

	private ArrayList<String> listeNomFichier;
	private String pathDossier;
	private BddManager dbManager;

	/**
	 * constructeur
	 * @param repertoire
	 */
	public Parser(File repertoire){
		listeNomFichier = new ArrayList<String>();
		dbManager = BddManager.getInstance();

		this.pathDossier = repertoire.getAbsolutePath();
		String[] listeFichiers;

		listeFichiers = repertoire.list();
		try {
			for(int i=0;i<listeFichiers.length;i++){
				if(listeFichiers[i].substring(0,1).equals("D"))
					this.listeNomFichier.add(listeFichiers[i]);
			}
		}catch(NullPointerException e){
			System.out.println("Folder provided Empty : Parser can't be constructed (NullPointerException)"+e.getMessage());
		}
	}

	/**
	 *  afichage de la liste des fichiers
	 */
	public void afficherListe(){
		System.out.println(listeNomFichier.toString());
	}

	/**
	 *  traite tous les mots de tous les fichiers, ie les insere ou pas dans la db
	 */
	public void parse(ArrayList<Mot> listeDeTousLesMots) {
		// parcours de tous les mots
		Date c=new Date();
		listeDeTousLesMots = this.affinerListe(listeDeTousLesMots);

		System.out.println("Parsing began "+listeDeTousLesMots.size()+ " " + c.toString());
		int count=0;
		for(int i=0;i<listeDeTousLesMots.size();i++){
			//traiter mot lent car acces a la bdd, on a fait le tri avant on va plutot inserer les mots cash
			//this.dbManager.traiter_mot(listeDeTousLesMots.get(i).getMot(), listeDeTousLesMots.get(i).getDocument(), listeDeTousLesMots.get(i).getBalise());
			try {
				this.dbManager.ajouterMot(listeDeTousLesMots.get(i).getMot(), listeDeTousLesMots.get(i).getDocument(), listeDeTousLesMots.get(i).getPonderation(),listeDeTousLesMots.get(i).getBalise());
			} catch (SQLException e) {
				e.printStackTrace();
			}
			if(count == 1500){
				count = 0;
				c = new Date();
				System.out.println(i+" / "+listeDeTousLesMots.size()+" "+c.toString());
			}else{
				count++;
			}
		}
	}
	
	/**
	 * Supprime les doublons dans la liste de tous les mots
	 * @param listeDeTousLesMots
	 * @return la liste plus legere
	 */
	private ArrayList<Mot> affinerListe(ArrayList<Mot> listeDeTousLesMots){
		System.out.println("Affinage de la liste :"+listeDeTousLesMots.size());
		ArrayList<Mot> toReturn = new ArrayList<Mot>();
		
		int count = 0;
		Mot curseur;
		Mot balayeur;
		int ponderationNouv=0;
		
		//pour tous les mots : on compte leurs occurences 
		for(int i=0;i<listeDeTousLesMots.size();i++){
			curseur = listeDeTousLesMots.get(i);
			ponderationNouv = curseur.getPonderation();
			count++;
			if(count == 1000){
				System.out.println(i + " / "+listeDeTousLesMots.size());
				count = 0;
			}
			for(int j=i;j<listeDeTousLesMots.size();j++){
				balayeur = listeDeTousLesMots.get(j);
				
				//les 2 mots sont identiques
				if(curseur.compareTo(balayeur) == 0){
					//on augmente la ponderation
					ponderationNouv = ponderationNouv +Parser.getPonderationFromBalise(curseur.getBalise());
					//on supprime le mot
					listeDeTousLesMots.remove(balayeur);
				}
			}
			curseur.setPonderation(ponderationNouv);
			toReturn.add(curseur);
			}
		System.out.println("Traitement effecute, gain de "+(toReturn.size()/listeDeTousLesMots.size())*100+"%");
		return toReturn;
	}

	/**
	 *  ajoute tous les mots de tous les fichiers dans uen seule liste
	 * @param nomFichiers
	 * @param balisesAParser
	 * @return
	 */
	public ArrayList<Mot> parsePlusieursFichiers(ArrayList<String> nomFichiers, ArrayList<String> balisesAParser){
		ArrayList<Mot> toReturn = new ArrayList<Mot>();

		//on parcourt la liste des fichiers
		for(int i=0;i<nomFichiers.size();i++){
			//recupere les mots du fichier
			ArrayList<Mot> motFichier = this.parseUnitaire(nomFichiers.get(i),balisesAParser);

			//pour chaque mot du fichier, on l"ajoute dans la premiere liste
			for(int j=0;j<motFichier.size();j++){
				toReturn.add(motFichier.get(j));
			}
		}
		return toReturn;
	}

	/**
	 * parse un fichier et renvoi la liste de ses mots
	 * @param nomDoc nom du document
	 * @param balisesAParser
	 * @return
	 */
	public ArrayList<Mot> parseUnitaire(String nomDoc, ArrayList<String> balisesAParser) {
		Convertisseur c = new Convertisseur(this.pathDossier);
		String	html = c.stringFromDocument(nomDoc);
		Document doc = null;
		String mots = null;	
		doc = Jsoup.parse(html);

		ArrayList<Mot> toReturn = new ArrayList<Mot>();
		//parcours de la liste des balises dont on veut les mots
		for(int i=0;i<balisesAParser.size();i++){
			//recupere uen balise
			String balise = balisesAParser.get(i);
			//on recupere les mots de la balise
			mots = Jsoup.parse(doc.getElementsByTag(balise).toString()).text();
			//on transforme ces mots séparés par des espaces en liste de mot

			/*	StringTokenizer st = new StringTokenizer(mots," \t\n\r\f,'\".;:!?|&");
			while (st.hasMoreTokens()) 
				//que l'on ajoute a la liste a retourner toReturn
				toReturn.add(new Mot(st.nextToken(),nomDoc,balise));
		}*/

			//explications regex : Tout ce qui n'est pas un caractere dans les crochet est considere comme delimiteur
			String[] parties = mots.split("[^a-zA-Z0-9éèàçù/]");

			//que l'on ajoute a la liste a retourner toReturn
			for(String s : parties){
				//tout en minuscule
				s = s.toLowerCase();
				//ne prend pas le mot vide et les mots de moins de 1 carac et on ne prend pas qu'une suite de chiffre
				if(!s.equalsIgnoreCase("") && s.length() >1 && !s.matches("[0-9]")){
					//Est-ce une date ?
					if(s.contains("/")){
						//DD-MM-YYY or YYYY-MM-DD
						if(s.matches("\\d{2}/\\d{2}/\\d{4}") || s.matches("\\d{4}/\\d{2}/\\d{2}")){
							toReturn.add(new Mot(s,nomDoc,balise));
						}
					}else{
						toReturn.add(new Mot(s,nomDoc,balise));
					}
				}
			}
		}
		return toReturn;
	}


	//listeBalise.add("title");
	//listeBalise.add("td");
	//listeBalise.add("caption");
	//listeBalise.add("div");
	//listeBalise.add("span");
	//listeBalise.add("span");
	//listeBalise.add("h1...");
	public static int getPonderationFromBalise(String balise){
		if(balise.equals("p")){
			return 2;
		}else if (balise.equals("li")){
			return 1;
		}else if (balise.equals("title")){
			return 10;
		}else if (balise.equals("td")){
			return 1;
		}else if (balise.equals("caption")){
			return 1;
		}else if (balise.equals("div")){
			return 1;
		}else if (balise.equals("span")){
			return 1;
		}else if (balise.equals("h1")){
			return 8;
		}else if (balise.equals("h2")){
			return 7;
		}else if (balise.equals("h3")){
			return 6;
		}else if (balise.equals("h4")){
			return 5;
		}else if (balise.equals("h5")){
			return 4;
		}else if (balise.equals("h6")){
			return 3;
		}else if (balise.equals("h7")){
			return 1;
		}else if (balise.equals("h8")){
			return 1;
		}else if (balise.equals("h9")){
			return 1;
		}else if (balise.equals("a")){
			return 1;
		}else 
			return 0;
	}

	//parcourir la liste listeNomFichier
	//pour chaque fichier
	//l ouvrir en lecture
	//le parser : balises p, title, h, li
	//supprimer les balises
	//pour chaque mot dans chaque balise
	//traiter_mot_BDD(mot,document,balise)


}
